/*
 * @Author: 麦冬果果
 * @Date: 2021-09-07 11:21:51
 * @LastEditTime: 2021-09-11 09:06:55
 * @LastEditors: 麦冬果果
 * @Description: 快速接口
 * @FilePath: /svc/src/app/service/fastApi.go
 * 可以输入预定的版权声明、个性签名、空行等
 */
package service

import (
	"fastapi/src/app/define"

	"github.com/gogf/gf/database/gdb"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gconv"
)

var FastApi = fastApi{}

type fastApi struct{}

/**
 * @description: 获取模型关联表
 * @param {[]map[string]interface{}} tableJoin
 * @param {*gdb.Model} m
 * @return {*}
 */
func (d *fastApi) ModelJoin(tableJoin []map[string]interface{}, m *gdb.Model) (result *gdb.Model, err error) {
	//查询是否是多表关联
	var tableJoins []*define.TableJoin
	gconv.Structs(tableJoin, &tableJoins)
	for _, v := range tableJoins {
		joinString := v.TableName1 + "." + v.Field1 + "=" + v.TableName2 + "." + v.Field2
		m = m.LeftJoin(v.TableName1, joinString)
	}
	return m, nil
}

/**
 * @description: 获取模型where条件
 * @param {[]map[string]interface{}} tableWhere
 * @param {*gdb.Model} m
 * @param {g.Map} req
 * @return {*}
 */
func (d *fastApi) ModelWhere(tableWhere []map[string]interface{}, m *gdb.Model, req g.Map) (result *gdb.Model, err error) {
	var tableWheres []*define.WhereBy
	gconv.Structs(tableWhere, &tableWheres)
	for _, v := range tableWheres {
		if v.Auth {
			//自定义数据权限,本部门,本部门及以下数据权限
			if req["dataScope"] == "2" || req["dataScope"] == "3" || req["dataScope"] == "4" {
				if v.Field == "dept" || v.Field == "dept_id" {
					m = m.WhereIn(v.TableName+"."+v.Field, req["deptScope"])
				}
			}
			//仅本人数据权限
			if req["dataScope"] == "5" && v.Field == "created_by" {
				m = m.Where(v.TableName+"."+v.Field, gconv.Uint(req["created_by"]))
			}
		}
		if g.IsEmpty(req[v.Params]) {
			continue
		}
		if v.Ways == "is" {
			if v.ParamsType == "string" {
				m = m.Where(v.TableName+"."+v.Field, gconv.String(req[v.Params]))
			}

			if v.ParamsType == "number" {
				m = m.Where(v.TableName+"."+v.Field, gconv.Uint64(req[v.Params]))
			}
		}

		if v.Ways == "in" {
			m = m.WhereIn(v.TableName+"."+v.Field, req[v.Params])
		}

		if v.Ways == "like" {
			value := "%" + gconv.String(req[v.Params]) + "%"
			m = m.WhereLike(v.TableName+"."+v.Field, value)
		}
		if v.Ways == "likem" {
			value := "%" + gconv.String(req[v.Params]) + "%"
			m = m.WhereLike(v.TableName+"."+v.Field, value)
		}
		if v.Ways == "likel" {
			value := gconv.String(req[v.Params]) + "%"
			m = m.WhereLike(v.TableName+"."+v.Field, value)
		}
		if v.Ways == "liker" {
			value := "%" + gconv.String(req[v.Params])
			m = m.WhereLike(v.TableName+"."+v.Field, value)
		}
		//between
		if v.Ways == "between" {
			value := gconv.Map(req[v.Params])
			m = m.WhereBetween(v.TableName+"."+v.Field, value["start"], value["end"])
		}

	}
	return m, nil
}

/**
 * @description: 获取模型order条件
 * @param {[]map[string]interface{}} tableOrder
 * @param {*gdb.Model} m
 * @return {*}
 */
func (d *fastApi) ModelOrder(tableOrder []map[string]interface{}, m *gdb.Model) (result *gdb.Model, err error) {
	var tableOrders []*define.OrderBy
	gconv.Structs(tableOrder, &tableOrders)
	for _, v := range tableOrders {
		m = m.OrderBy(v.OrderTable + "." + v.OrderField + "  " + v.Sort + " ")
	}
	return m, nil
}

/**
 * @description: 获取模型group条件
 * @param {[]map[string]interface{}} tableGroup
 * @param {*gdb.Model} m
 * @return {*}
 */
func (d *fastApi) ModelGroup(tableGroup []map[string]interface{}, m *gdb.Model) (result *gdb.Model, err error) {
	var tableGroups []*define.GroupBy
	gconv.Structs(tableGroup, &tableGroups)
	for _, v := range tableGroups {
		m = m.GroupBy(v.GroupTable + "." + v.GroupField)
	}
	return m, nil
}

/**
 * @description: 获取模型field
 * @param {[]map[string]interface{}} tableField
 * @param {*gdb.Model} m
 * @return {*}
 */
func (d *fastApi) ModelField(tableField []map[string]interface{}, m *gdb.Model) (result *gdb.Model, err error) {
	var tableFields []*define.FieldBy
	gconv.Structs(tableField, &tableFields)
	fieldArray := []string{}
	for _, v := range tableFields {
		if v.Fields != "*" {
			fieldString := v.FieldTable + "." + v.Fields
			if v.FieldAs != "" {
				fieldString += " as " + v.FieldAs
			}
			fieldArray = append(fieldArray, fieldString)
		} else {
			fieldString := v.FieldTable + ".*"
			fieldArray = append(fieldArray, fieldString)
		}
	}
	value := gconv.Strings(fieldArray)
	m = m.Fields(value)
	return m, nil
}

/**
 * @description: 获取模型写入数据
 * @param {[]map[string]interface{}} tableField
 * @param {*gdb.Model} m
 * @param {g.Map} params
 * @return {*}
 */
func (d *fastApi) ModelData(tableField []map[string]interface{}, m *gdb.Model, params g.Map) (*gdb.Model, error) {
	var tableFields []*define.FieldBy
	gconv.Structs(tableField, &tableFields)
	data := g.Map{}
	for _, v := range tableFields {
		// if v.Fields == "" && !g.IsEmpty(params[v.Fields]) {
		// 	data[v.Fields] = params[v.Fields]
		// }
		data[v.Fields] = params[v.Fields]
		if v.FieldAs != "" { //&& !g.IsEmpty(params[v.FieldAs])
			data[v.Fields] = params[v.FieldAs]
		}
	}
	m = m.Data(data)
	return m, nil
}

/**
 * @description: 获取查询模型
 * @param {*define.AppApi} appApi
 * @param {g.Map} params
 * @return {*}
 */
func (d *fastApi) GetFindModel(appApi *define.AppApi, params g.Map) (m *gdb.Model, err error) {

	if appApi == nil {
		err = gerror.New("接口数据不能为空")
		return
	}
	m = g.DB("default").Model(appApi.TableName).Safe()
	//查询是否是多表关联

	tableJoins := gconv.SliceMapDeep(appApi.TableJoin)
	if len(tableJoins) != 0 {
		m, err = d.ModelJoin(tableJoins, m)
	}

	//where 查询
	tableWhere := gconv.SliceMapDeep(appApi.WhereBy)
	if len(tableWhere) != 0 {
		m, err = d.ModelWhere(tableWhere, m, params)
	}

	//order
	tableOrder := gconv.SliceMapDeep(appApi.OrderBy)
	if len(tableOrder) != 0 {
		m, err = d.ModelOrder(tableOrder, m)
	}

	//group
	tableGroup := gconv.SliceMapDeep(appApi.GroupBy)
	if len(tableGroup) != 0 {
		m, err = d.ModelGroup(tableGroup, m)
	}

	//fields
	tableField := gconv.SliceMapDeep(appApi.FieldBy)
	if len(tableField) != 0 {
		m, err = d.ModelField(tableField, m)
	}

	if err != nil {
		return nil, err
	}
	return
}

/**
 * @description: 获取编辑模型
 * @param {*define.AppApi} appApi
 * @param {g.Map} params
 * @return {*}
 */
func (d *fastApi) GetEditModel(appApi *define.AppApi, params g.Map) (m *gdb.Model, err error) {
	if appApi == nil {
		err = gerror.New("接口数据不能为空")
		return
	}
	if g.IsEmpty(params) {
		err = gerror.New("参数不能为空")
		return
	}

	m = g.DB("default").Model(appApi.TableName).Safe()
	//查询是否是多表关联
	tableJoins := gconv.SliceMapDeep(appApi.TableJoin)
	if len(tableJoins) != 0 {
		m, err = d.ModelJoin(tableJoins, m)
	}
	//where 查询

	tableWhere := gconv.SliceMapDeep(appApi.WhereBy)
	if len(tableWhere) != 0 {
		m, err = d.ModelWhere(tableWhere, m, params)
	}
	//data
	tableField := gconv.SliceMapDeep(appApi.FieldBy)
	if len(tableField) != 0 {
		m, err = d.ModelData(tableField, m, gconv.Map(params))
	}

	if err != nil {
		return nil, err
	}
	return
}
